#include "cbrowserwindow.h"
#include "cbrowserapp.h"

#include <buola/gui/cmenu.h>
#include <buola/widgets/ceditbox.h>
#include <buola/io/cfile.h>
#include <buola/io/cfilefilter.h>
#include <buola/widgets/cstatusbar.h>
#include <buola/widgets/ctoolbar.h>
#include <buola/widgets/cmenubar.h>
#include <buola/widgets/ctheme.h>

namespace buola { namespace browser {

CBrowserWindow::CBrowserWindow(CBrowserApp *pApp)
    :   mApp(pApp)
{
    mHistoryPos=-1;

    mStartURI=io::get_home();

    SetTitle(L"browser");

    mFileList=new gui::CFileList;
    mFileList->sSelected.Connect(&CBrowserWindow::OnListSelected,this);
    mFileList->eDblClick.Connect(&CBrowserWindow::OnListDblClick,this,_1);
    mFileList->sFillMenu.Connect(&CBrowserWindow::OnListFillMenu,this,_1);
    mFileList->eIntAction.Connect(&CBrowserWindow::OnIntAction,this,_1,_2);
    mFileList->SetStyleBit(gui::CListBox::STYLE_USERMENU);
    mFileList->SetURI(io::get_cwd());
    Attach(mFileList,gui::ATTACH_REPLACECLIENT);
    
    mDirTree=new gui::CDirTree;
    mDirTree->sSelected.Connect(&CBrowserWindow::OnTreeSelected,this,_1);
    mDirTree->sFillMenu.Connect(&CBrowserWindow::OnTreeFillMenu,this,_1);
    mDirTree->SetIconSize(gui::CIcon::SMALL);
    mDirTree->SetStyleBit(gui::CTreeBox::STYLE_HIERARCHYLINES);
    mDirTree->SetURI(io::file("/"));
    mDirTree->SetFilter(new io::CFlagsFileFilter(io::CFlagsFileFilter::NOFILES));
    Attach(mDirTree,gui::ATTACH_WEST,gui::ATTACH_BAR|gui::ATTACH_VERTICAL|gui::ATTACH_CLOSE);

    gui::PMenu lMenu=new gui::CMenu;

    lMenu->Add(gui::new_menu_item(L"up",ICON_STOCK_UP))->eTriggered.Connect(&CBrowserWindow::Navigate,this,NAV_UP);
    lMenu->Add(gui::new_menu_item(L"back",ICON_STOCK_PREVIOUS))->eTriggered.Connect(&CBrowserWindow::Navigate,this,NAV_BACK);
    lMenu->Add(gui::new_menu_item(L"forward",ICON_STOCK_NEXT))->eTriggered.Connect(&CBrowserWindow::Navigate,this,NAV_FORWARD);
    lMenu->Add(gui::new_menu_item(L"home",ICON_STOCK_HOME))->eTriggered.Connect(&CBrowserWindow::Navigate,this,NAV_HOME);

    mToolBar=new gui::CToolBar(lMenu);
    Attach(mToolBar,gui::ATTACH_NORTH,gui::ATTACH_TOOLBAR);

    mEdit=new gui::CEditBox;
    mEdit->eEnter.Connect([&](const std::wstring &pS){this->SetWorkingURI(io::uri(pS),true,true);});
    ///\todo this
    //mEdit->SetStyleBit(STYLE_INBAR);
    lMenu->AddWindow(mEdit);

    mStatusBar=new gui::CStatusBar;
    mStatusBar->AddItem(L"0/0",nullptr,1);
    Attach(mStatusBar,gui::ATTACH_SOUTH,gui::ATTACH_STATUSBAR);

    SetIcon(gui::CIcon::Get("folder"));
}

void CBrowserWindow::SetWorkingURI(const io::CURI &pURI,bool pActHistory,
                bool pUpdateTree)
{
    if(!Mapped())
    {
        mStartURI=pURI;
        mStartURI.MakeAbsolute(io::get_cwd());
        return;
    }

    if(mURI==pURI) return;
    mURI=pURI;
    mURI.MakeAbsolute(io::get_cwd());
    mStartURI=mURI;
    
    mFileList->SetURI(mURI);
    mEdit->SetCaption(mURI.ToWString());
    
    if(pActHistory)
    {
        while(mHistory.size()>mHistoryPos+1)
        {
            mHistory.erase(mHistory.begin()+mHistoryPos+1);
            
        }
        
        mHistoryPos++;
        mHistory.push_back(mURI);
    }
    
    if(pUpdateTree)
    {
        if(mURI.SchemeName()=="file")
            mDirTree->SelectDir(mURI);
    }

    std::string lName=mURI.Name();
    if(lName.empty())
        SetTitle(L"/");
    else
        SetTitle(utf32(lName));
}

void CBrowserWindow::Navigate(ENav pWhere)
{
    if(pWhere==NAV_HOME)
    {
        SetWorkingURI(io::get_home());
    }
    else if(pWhere==NAV_UP)
    {
        io::CURI lURI=mURI;
        lURI.MakeParent();
        SetWorkingURI(lURI);
    }
    else if(pWhere==NAV_BACK)
    {
        if(mHistoryPos>0)
        {
            mHistoryPos--;
            SetWorkingURI(mHistory[mHistoryPos],false);
        }
    }
    else if(pWhere==NAV_FORWARD)
    {
        if(mHistoryPos+1<mHistory.size())
        {
            mHistoryPos++;
            SetWorkingURI(mHistory[mHistoryPos],false);
        }
    }
}

void CBrowserWindow::OnListFillMenu(gui::PMenu pMenu)
{
    pMenu->Add(gui::new_menu_item(L"up",ICON_STOCK_UP))->eTriggered.Connect(&CBrowserWindow::Navigate,this,NAV_UP);
    pMenu->Add(gui::new_menu_item(L"back",ICON_STOCK_PREVIOUS))->eTriggered.Connect(&CBrowserWindow::Navigate,this,NAV_BACK);
    pMenu->Add(gui::new_menu_item(L"forward",ICON_STOCK_NEXT))->eTriggered.Connect(&CBrowserWindow::Navigate,this,NAV_FORWARD);
    pMenu->Add(gui::new_menu_item(L"home",ICON_STOCK_HOME))->eTriggered.Connect(&CBrowserWindow::Navigate,this,NAV_HOME);
}

void CBrowserWindow::OnTreeFillMenu(gui::PMenu pMenu)
{
    pMenu->Add(gui::new_menu_item(L"up",ICON_STOCK_UP))->eTriggered.Connect(&CBrowserWindow::Navigate,this,NAV_UP);
    pMenu->Add(gui::new_menu_item(L"back",ICON_STOCK_PREVIOUS))->eTriggered.Connect(&CBrowserWindow::Navigate,this,NAV_BACK);
    pMenu->Add(gui::new_menu_item(L"forward",ICON_STOCK_NEXT))->eTriggered.Connect(&CBrowserWindow::Navigate,this,NAV_FORWARD);
    pMenu->Add(gui::new_menu_item(L"home",ICON_STOCK_HOME))->eTriggered.Connect(&CBrowserWindow::Navigate,this,NAV_HOME);
}

void CBrowserWindow::OnTreeSelected(gui::CTreeBox::SNode *pNode)
{
    SetWorkingURI(mDirTree->GetURI(pNode),true,false);
}

void CBrowserWindow::OnListDblClick(gui::CListBox::SItem *pItem)
{
    io::CFile lFile(mFileList->GetURI(pItem));
    
    if(lFile.IsFolder())
        SetWorkingURI(mFileList->GetURI(mFileList->GetItemByID(pItem->mID)));
}

void CBrowserWindow::OnListSelected()
{
    io::CFile lFile=mFileList->GetSelectedFile();
    if(lFile)
        mStatusBar->SetItemText(1,L"aaaa");//lInterface->GetStatusLine());
}

void CBrowserWindow::OnIntAction(gui::TID pAction,const io::CURI &pURI)
{
    if(pAction==1)//CFileInterface::OPEN_URI)
    {
        SetWorkingURI(pURI);
    }
    else if(pAction==2)//CFileInterface::SELECT_URI)
    {
        SetWorkingURI(pURI.GetParent());
        for(int i=0;i<mFileList->GetItemCount();i++)
        {
            gui::CListBox::SItem *lItem=mFileList->GetItemByPos(i);
            if(mFileList->GetURI(lItem)==pURI)
            {
                mFileList->SelectItem(lItem);
                mFileList->EnsureVisible(lItem,false);
            }
        }
    }
}

void CBrowserWindow::OnShow()
{
    if(mURI!=mStartURI)
        SetWorkingURI(mURI);
}

/*namespace browser*/ } /*namespace buola*/ }
